`include "/home/lab/lab14/Computer_architecture/homwork/register/src/register.v"
module tb_register ();
    reg LD,CLK;
    reg [2:0] DR,SR1,SR2;
    reg [15:0] DR_IN;
    wire [15:0] SR1_OUT,SR2_OUT;

    //reference varriable
    reg   [15:0]    reg_f [7:0] = '{default:0};;//Set a virtual registerfile to store the reference data
    reg   [15:0]    expect1;
    reg   [15:0]    expect2;
    reg [15:0] sd;


    //Conect to the DUT
    register reg_file(
    .LD(LD),
    .CLK(CLK),
    .DR(DR),
    .SR1(SR1),
    .SR2(SR2),
    .DR_IN(DR_IN),
    .SR1_OUT(SR1_OUT),
    .SR2_OUT(SR2_OUT)
    );

    
    //Initialise the register_file
    initial begin
        LD    = 1;
        SR1   = 0;
        SR2   = 0;
        DR_IN = 0;
        DR    = 0;
        #2 DR = DR+1;
        #2 DR = DR+1;
        #2 DR = DR+1;
        #2 DR = DR+1;
        #2 DR = DR+1;
        #2 DR = DR+1;
        #2 DR = DR+1;
        #2 LD = 0;
    end

    //Set up the clock
    initial begin
        CLK = 1;
        repeat(150)begin
            #1 CLK = ~CLK;
        end
    end

    //Build up the moniter module
    task reference(
        input [2:0] SR1,SR2,
        input [15:0] SR1_OUT,SR2_OUT,
        input [15:0] expect1,expect2
        );
        if (SR1_OUT !== expect1 && LD == 0)begin
            $display("READ1 FALIED!!!");
            $display("At time %0t and REG-FIEL-adress %h : the read-value of is %h and should be %h",$time,SR1,SR1_OUT,expect1);
        end
        else begin
            $display("At time %0t. and REG-FIEL-adress %h : the read-value of is %h. READ1 PASSED!!!",$time,SR1,SR1_OUT);
        end
        if (SR2_OUT !== expect2 && LD == 0)begin
            $display("READ2 FALIED!!!");
            $display("At time %0t and REG-FIEL-adress %h : the read-value of is %h and should be %h",$time,SR2,SR2_OUT,expect2);
        end
        else begin
            $display("At time %0t and REG-FIEL-adress %h : the read-value of is %h READ2 PASSED!!!",$time,SR2,SR2_OUT);
        end
    endtask

//get randow value for the DUT
    initial
    begin
        //利用系统函数$get_initial_random_seed获得 randomd使用需要的种子
        //sd = 0;
        //$get_initial_random_seed();
        #15
        repeat(50)              //获得20组随机输入
        begin
            #2//每2ns更新一次随机输入
            LD = $random % 2;
            DR = DR+{$random} % 4;
            //每执行一次$random(seed)产生一个随机数，seed也自动更新一次。
            SR1   = SR1+{$random} % 4;
            SR2   = SR2+{$random} % 4;
            DR_IN = {$random % 17'h10000};
            //等待DUT结果出来
            //计算理想情况下的情况
            if (LD)  begin
                reg_f[DR] = DR_IN;
            end
            expect1 = reg_f[SR1];
            expect2 = reg_f[SR2];
            reference(SR1,SR2,SR1_OUT,SR2_OUT,expect1,expect2);
        end
        $display("TEST FINISH!");
        $finish;
    end
    initial begin
        //$display("start a clock pulse");
        $dumpfile("tb_register.vcd");
        $dumpvars(1,tb_register);
    end
endmodule
